﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InHD.commands;
using System.Windows.Input;
using System.ComponentModel;
using InHD.model;
using InHD.dataaccess;
using System.Data;
using System.Windows.Documents;
using System.Windows.Markup;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media;

namespace InHD.viewmodels
{
    class TransactionViewModel : WorkspaceViewModel, IDataErrorInfo
    {
        #region Value Property
        readonly Transaction _transaction;
        readonly TransactionRepository _transactionRepository;
        #endregion

        #region Commands
       
        private RelayCommand _commitCommand;
        private RelayCommand _cancelCommand;
        private RelayCommand _selectCustomerCommand;
        private RelayCommand _addProductCommand;
        private RelayCommand _addPaymentCommand;
        private RelayCommand _removeProductCommand;
        private RelayCommand _editProductCommand;
        private RelayCommand _commitDialogProductCommand;
        
        public void Commit(object param)
        {
            //Print Test Here
            CreateAndPrintDocument();
        }

        bool CanCommit
        {
            get { return true; }
        }
        #endregion

        #region Constructor

        public TransactionViewModel(Transaction transaction, TransactionRepository transactionRepository)
        {
            if (transaction == null)
                throw new ArgumentNullException("transaction");
            if (transactionRepository == null)
                throw new ArgumentNullException("transactionRepository");

            this._transaction = transaction;
            this._transactionRepository = transactionRepository;

            if (dataTable == null)
            {
                dataTable = new DataTable();
                dataTable.Columns.Add("Name");
                dataTable.Columns.Add("Description");
                dataTable.Columns.Add("Category");
                dataTable.Columns.Add("Tax");
                dataTable.Columns.Add("Quantity");
            }
        }

        #endregion

        #region IDataErrorInfo Members

        string IDataErrorInfo.Error
        {
            get { return (_transaction as IDataErrorInfo).Error; }
        }

        string IDataErrorInfo.this[string propertyName]
        {
            get
            {
                string error = null;


                error = (_transaction as IDataErrorInfo)[propertyName];


                // Dirty the commands registered with CommandManager,
                // such as our Save command, so that they are queried
                // to see if they can execute now.
                CommandManager.InvalidateRequerySuggested();

                return error;
            }
        }

        #endregion // IDataErrorInfo Members

        #region Presentation Properties

        InHD.views.usercontrols.ProductEditDialog editProductDialog = null;

        public string StaffName
        {
            get { return "User " + _transaction.StaffUnk.ToString(); }  ////Replace Later by GetStaffById
            set { StaffName = value; }
        }

        public DataTable dataTable
        {
            get;
            set;
        }

        public int RowIndex { get; set; }

        public string product
        {
            get;
            set;
        }

        public string description
        {
            get;
            set;
        }

        public DataTable sourceCategory { get; set; }

        public int index { get; set; }

        public FlowDocument MyDocument { get; set; }

        /// <summary>
        /// Returns a command that add new Product.
        /// </summary>
        public ICommand AddNewProductCommand
        {
            get
            {
                if (_addProductCommand == null)
                {
                    _addProductCommand = new RelayCommand(
                        (param) => this.AddProduct());
                }
                return _addProductCommand;
            }
        }

        /// <summary>
        /// Returns a command that remove the product.
        /// </summary>
        public ICommand RemoveProductCommand
        {
            get
            {
                if (_removeProductCommand == null)
                {
                    _removeProductCommand = new RelayCommand(
                        (param) => this.RemoveProduct());
                }
                return _removeProductCommand;
            }
        }

        /// <summary>
        /// Returns a command that edit the product.
        /// </summary>
        public ICommand CommitDialogProductCommand
        {
            get
            {
                if (_commitDialogProductCommand == null)
                {
                    _commitDialogProductCommand = new RelayCommand(
                        (param) => this.CommitEditProduct());
                }
                return _commitDialogProductCommand;
            }
        }

        /// <summary>
        /// Returns a command that edit the product.
        /// </summary>
        public ICommand EditProductCommand
        {
            get
            {
                if (_editProductCommand == null)
                {
                    _editProductCommand = new RelayCommand(
                        (param) => this.EditProduct());
                }
                return _editProductCommand;
            }
        }

        /// <summary>
        /// Returns a command that commit Window
        /// </summary>
        public ICommand CommitCommand
        {
            get
            {
                if (_commitCommand == null)
                {
                    _commitCommand = new RelayCommand(
                        (param) => this.Commit(param), (param) => this.CanCommit);
                }
                return _commitCommand;
            }
        }

        #endregion

        #region Command Method

        void AddProduct()
        {
            if (dataTable == null)
            {
                dataTable = new DataTable();
                dataTable.Columns.Add("Name");
                dataTable.Columns.Add("Description");
                dataTable.Columns.Add("Category");
                dataTable.Columns.Add("Tax");
                dataTable.Columns.Add("Quantity");
            }
            else
            {
                DataRow newRow = dataTable.NewRow();
                newRow["Name"] = "New Product";
                newRow["Description"] = "For Sale";
                newRow["Category"] = "XXX";
                newRow["Tax"] = 0.15;
                newRow["Quantity"] = 10;
                dataTable.Rows.Add(newRow);
                dataTable.AcceptChanges();
            }
        }

        void RemoveProduct()
        {
            int tmp = RowIndex;
            RowIndex = 0;
            dataTable.Rows[tmp].Delete();
        }

        void EditProduct()
        {
            editProductDialog = new views.usercontrols.ProductEditDialog();
            editProductDialog.DataContext = this;
            product = dataTable.Rows[RowIndex]["Name"].ToString();
            description = dataTable.Rows[RowIndex]["Description"].ToString();
            sourceCategory = new DataTable();
            sourceCategory.Columns.Add("tam");
            DataRow row = sourceCategory.NewRow();
            row[0] = "Leaf";
            sourceCategory.Rows.Add(row);
            row = sourceCategory.NewRow();
            row[0] = "Fire";
            sourceCategory.Rows.Add(row);
            row = sourceCategory.NewRow();
            row[0] = "Storm";
            sourceCategory.Rows.Add(row);
            row = sourceCategory.NewRow();
            row[0] = "XXX";
            sourceCategory.Rows.Add(row);
            string category = dataTable.Rows[RowIndex]["Category"].ToString();
            for (int i=0; i<sourceCategory.Rows.Count; i++) if (sourceCategory.Rows[i][0].ToString().Equals(category))
                {
                    index = i;
                    break;
                }
            if (editProductDialog.ShowDialog() == true)
            {
                dataTable.Rows[RowIndex]["Name"] = product;
                dataTable.Rows[RowIndex]["Description"] = description;
                dataTable.Rows[RowIndex]["Category"] = sourceCategory.Rows[index][0].ToString();
                sourceCategory.Rows.Clear();
            }
        }

        void CommitEditProduct()
        {
            editProductDialog.DialogResult = true;
            editProductDialog.Close();
        }

        #endregion

        #region Normal Method
        void CreateAndPrintDocument()
        {
            FileStream stream = new FileStream("../../media/templateSale.xaml", FileMode.Open);
            MyDocument = XamlReader.Load(stream) as FlowDocument;
            Table tableContent = null;
            //foreach (Block block in MyDocument.Blocks)
            //{
            //    if (block.Name.Equals("tableContent"))
            //    {
            //        tableContent = block as Table;
            //        break;
            //    }
            //}

            //stream = new FileStream("..\\..\\media\\template1.xaml", FileMode.Open);
            tableContent = System.Windows.LogicalTreeHelper.FindLogicalNode(MyDocument as System.Windows.DependencyObject, "tableContent") as Table;
            stream.Close();

            if (tableContent == null)
            {
                //TODO: Error Template load
            }

            int rowCount = 0;
            foreach (DataRow dataRow in dataTable.Rows)
            {
                rowCount++;
                TableRow row = new TableRow();
                TableCell cell = new TableCell(); cell.BorderThickness = new System.Windows.Thickness(1,0,1,1);
                cell.BorderBrush = Brushes.Black;
                Paragraph paragraph = new Paragraph();
                paragraph.Inlines.Add(rowCount.ToString());
                cell.Blocks.Add(paragraph);
                row.Cells.Add(cell);

                cell = new TableCell(); cell.BorderThickness = new System.Windows.Thickness(0, 0, 1, 1);
                cell.BorderBrush = Brushes.Black;
                paragraph = new Paragraph();
                paragraph.Inlines.Add(dataRow["Name"].ToString());
                cell.Blocks.Add(paragraph);
                row.Cells.Add(cell);

                cell = new TableCell(); cell.BorderThickness = new System.Windows.Thickness(0, 0, 1, 1);
                cell.BorderBrush = Brushes.Black;
                paragraph = new Paragraph();
                paragraph.Inlines.Add("unit");
                cell.Blocks.Add(paragraph);
                row.Cells.Add(cell);

                cell = new TableCell(); cell.BorderThickness = new System.Windows.Thickness(0, 0, 1, 1);
                cell.BorderBrush = Brushes.Black;
                paragraph = new Paragraph();
                paragraph.Inlines.Add(dataRow["Quantity"].ToString());
                cell.Blocks.Add(paragraph);
                row.Cells.Add(cell);

                cell = new TableCell(); cell.BorderThickness = new System.Windows.Thickness(0, 0, 1, 1);
                cell.BorderBrush = Brushes.Black;
                paragraph = new Paragraph();
                paragraph.Inlines.Add(dataRow["Tax"].ToString());
                cell.Blocks.Add(paragraph);
                row.Cells.Add(cell);

                cell = new TableCell(); cell.BorderThickness = new System.Windows.Thickness(0, 0, 1, 1);
                cell.BorderBrush = Brushes.Black;
                paragraph = new Paragraph();
                double total = Convert.ToDouble(dataRow["Tax"]) * Convert.ToDouble(dataRow["Quantity"]);
                paragraph.Inlines.Add(total.ToString());
                cell.Blocks.Add(paragraph);
                row.Cells.Add(cell);

                tableContent.RowGroups[0].Rows.Add(row);
            }

            InHD.views.usercontrols.PrintPreview previewDlg = new InHD.views.usercontrols.PrintPreview();

            previewDlg.DataContext = this;
            previewDlg.ShowDialog();

            PrintDialog dlg = new PrintDialog();
            ((IDocumentPaginatorSource)MyDocument).DocumentPaginator.PageSize = new System.Windows.Size(816, 1248);
            MyDocument.PageHeight = dlg.PrintableAreaHeight;
            MyDocument.PageWidth = dlg.PrintableAreaWidth;
            MyDocument.PagePadding = new System.Windows.Thickness(50);
            MyDocument.ColumnGap = 0;
            MyDocument.ColumnWidth = dlg.PrintableAreaWidth;

            if (dlg.ShowDialog() == true)
            {
                dlg.PrintDocument(((IDocumentPaginatorSource)MyDocument).DocumentPaginator, "");
            }
        }
        #endregion
    }
}
